package org.starti.metadata;

import java.lang.reflect.Method;
import java.util.Collection;


/**
 * <p>This is a Service Provider Interface for an implementation that returns composed metadata.  It should never be called
 * by clients directly, only by the current system MetadataManager.</p>
 *
 * @author <a href="mailto:claudiu.dumitrescu@gmail.com">Claudiu Dumitrescu</a>
 */
public interface MetadataFactory {
    /**
     * Compose an implementation of Metadata for the Class object provided to this method.  The Metadata object that is
     * returned is a proper composition of all the MetadataProviders that were registered in the startup configuration.
     *
     * @param element A Class object that we would like to recover Metadata for
     * @return A Metadata object
     */
    Metadata createClass(Class element);

    /**
     * Like createClass(), but do so for a Property of the class we are building metadata for.
     *
     * @param element A JavaBean semantic [getX() setX()] accessor method for a field
     * @return A Metadata object
     */
    Metadata createProperty(Method element);

    /**
     * Like createClass(), but do so for a Method of the class we are building metadata for.  This is distinct from createProperty()
     * as it is for a functional method of a bean, not a JavaBean accessor.
     *
     * @param element A functional (not accessor) method of a bean
     * @return A Metadata object
     */
    Metadata createMethod(Method element);

    /**
     * Get the list of MetadataProviders that would contribute to a Metadata object that is composed.
     *
     * @return Collection of MetadataProviders
     */
    Collection<MetadataProvider> getProviders();
}
